Skip to content

fix(scripts): resolve invoke_separator by parse success, not python3 availability (#3304)#3320

Open
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/3304-invoke-separator-python3-stub
Open

fix(scripts): resolve invoke_separator by parse success, not python3 availability (#3304)#3320
Noor-ul-ain001 wants to merge 1 commit into
github:mainfrom
Noor-ul-ain001:fix/3304-invoke-separator-python3-stub

Conversation

@Noor-ul-ain001

Copy link
Copy Markdown
Contributor

Summary

Follow-up to #3304. The primary report and PR #3312 fix the feature.json
parser (read_feature_json_feature_directory), but the reporter explicitly
asked that other python3 call sites be grepped for the same pattern.
This fixes the one remaining site that has the defect: get_invoke_separator.

get_invoke_separator in scripts/bash/common.sh selected its JSON parser by
tool availability (command -v python3) rather than parse success, and —
unlike the feature.json parser — had no text fallback at all after the
python3 branch. On a stock Windows machine under Git Bash (no jq; python3
resolving to the Microsoft Store App Execution Alias stub that satisfies
command -v but exits 49 at runtime), it silently returned "." even for
integrations that use a - separator (e.g. forge, cline).

The observable symptom is wrong command hints in user-facing error messages
check-prerequisites.sh and setup-tasks.sh print e.g.
Run /speckit.plan first instead of the correct /speckit-plan.

Changes

  • scripts/bash/common.sh (get_invoke_separator):

    • Restructure the jq → python3 cascade to fall through on parse failure,
      gated on a parsed success flag rather than exclusive elif-on-availability
      branches (mirrors the approach in fix(scripts): fall through to grep/sed when python3 is a broken stub in feature.json parser #3312).
    • Make the python3 branch signal failure (sys.exit(1)) instead of
      printing ".", so a stub failure falls through instead of being accepted as
      a valid answer.
    • Add an awk text fallback for environments with neither jq nor a working
      python3. It reads the active integration key (default_integration, else
      integration) and its invoke_separator from within integration_settings.
      Portable (no gawk-only RS="^$" whole-file slurp, so BSD awk / macOS is
      fine) and handles both pretty-printed (the written form) and compact JSON.
      Malformed input safely defaults to ".".
  • tests/test_setup_tasks.py: regression test that simulates the broken
    environment (jq + python3 stubs that exit 49, prepended to PATH) and
    asserts the - separator is still recovered (/speckit-plan).

Scope note

The other two python3 call sites in common.sh (resolve_template,
resolve_template_content) already wrap the call in if …python3…; then … else <fallback> fi, so a stub failure correctly falls into their unordered-scan
fallback. They are unaffected and left unchanged. This PR does not touch
read_feature_json_feature_directory (covered by #3312), so the two PRs are
non-overlapping.

Verification

Reproduced on a machine that is the affected environment (no jq, python3 =
Windows Store stub): before the fix format_speckit_command plan emits
/speckit.plan; after, /speckit-plan. Validated the parser across pretty /
compact / dot-default / empty-settings / malformed inputs, and under
set -euo pipefail.

🤖 Generated with Claude Code

…back (github#3304)

`get_invoke_separator` in common.sh selected its JSON parser by tool
*availability* (`command -v python3`) rather than parse *success*, and had
no text fallback after the python3 branch. On stock Windows + Git Bash —
no jq, and `python3` resolving to the Microsoft Store App Execution Alias
stub that passes `command -v` but exits 49 at runtime — it silently fell
back to "." even for `-`-separator integrations (e.g. forge, cline). The
observable result was wrong command hints in error messages, such as
`/speckit.plan` instead of `/speckit-plan`, in check-prerequisites.sh and
setup-tasks.sh.

This is the same existence-vs-runtime pattern fixed for the feature.json
parser in github#3304's primary report; the reporter explicitly asked that other
python3 call sites be checked. The two remaining sites (resolve_template,
resolve_template_content) already fall through on failure and are unaffected.

- Restructure the jq -> python3 chain to fall through on parse failure,
  gated on a `parsed` success flag rather than exclusive elif branches.
- Make the python3 branch signal failure (sys.exit(1)) instead of printing
  "." so a stub failure falls through instead of being accepted.
- Add an awk text fallback (portable, no gawk-only whole-file slurp) that
  reads the active integration key and its invoke_separator, handling both
  pretty-printed (the written form) and compact JSON. Malformed input
  safely defaults to ".".

Regression test simulates the broken-stub environment (jq + python3 stubs
that exit 49 on PATH) and asserts the `-` separator is still recovered.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant